Skip to content

add i18n foundation with Arabic while maintaining Google Translate for progressive migration, fix translation issues, and improve language selector UX#241

Merged
mattqdev merged 19 commits intophysicshub:mainfrom
FaresAyadi055:main
Mar 26, 2026
Merged

add i18n foundation with Arabic while maintaining Google Translate for progressive migration, fix translation issues, and improve language selector UX#241
mattqdev merged 19 commits intophysicshub:mainfrom
FaresAyadi055:main

Conversation

@FaresAyadi055
Copy link
Copy Markdown
Contributor

ChangeLogs

Summary

Adds i18n infrastructure with Arabic language support while maintaining Google Translate for a progressive migration path.
fixed google translate related issues.

afftected files

  • app/(core)/components/ContributorsSection.jsx
  • app/(core)/components/GoogleTranslator.jsx
  • app/(core)/components/Hero.jsx

new files

  • app/(core)/hooks/useTranslation.ts
  • app/(core)/locales/(ar,de,en,es,fr,it).json
  • app/(core)/locales/meta.json

found issues and fixes

1. language options are in english and affected by translations (resolved):

In app/(core)/components/GoogleTranslator.jsx
the language options are defined as:

const LANGUAGES = {
  en: "English",
  it: "Italian",
  fr: "French",
  de: "German",
  es: "Spanish",
};

I changed it to:

const LANGUAGES = {
  en: "English",
  it: "Italiano",
  fr: "Français",
  de: "Deutsch",
  es: "Español"
};

This allows people that can't read english to Identify their language immediatly,
this UX change is especially critical for speakers that can't read the Latin alphabet.

We also have to prevent Google translate from messing with them and keep them as they are.
before:

            <option key={code} value={code}>{name}</option>

after:

            <option
              key={code}
              value={code}
              translate="no"
              className="notranslate"
            >
              {name}
            </option>

the translate="no" attribute and the notranslate class will make google translate ignore the text.

2. preventing contributors github user names from being translated (resolved):

in app/(core)/components/ContributorsSection.jsx we find contributors card that displays their info,
the issue is that they are affected by google translate which can alter them.
To fix it I added

<p className="contributor-name" translate="no">

inside the className="contributor-info" div.

3. language select doesn't have a state and it default to English on reload (resolved):

in app/(core)/components/GoogleTranslator.jsx when selecting a language other than English like for example Spanish, then we reload the page, the page remains translated in Spanish but the selector dispalys "English" as it is the hardcoded initial value.
to fix it I used this helper function:

// Helper to extract language from googtrans cookie
const getGoogleTransLang = () => {
  const getCookie = (name) => {
    if (typeof document === "undefined") return null;
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop()?.split(";").shift();
    return null;
  };
  const cookie = getCookie("googtrans");
  if (cookie) {
    const parts = cookie.split("/");
    if (parts.length >= 3) {
      return parts[2]; // e.g., /en/it -> it
    }
  }
  return "en";
};

my current implementation only works with the added features I made.

Added features:

1. added arabic:

arabic is now available in both google translate and i18n:

const LANGUAGES = {
  en: "English",
  it: "Italiano",
  fr: "Français",
  de: "Deutsch",
  es: "Español",
  ar: "العربية",
};

2- added app/(core)/hooks/useTranslation.ts:

useTranslation is a hook that provides internationalization (i18n) capabilities for Next.js

  • how to use ?

first in a componentor page we import this hook then we define:

const { t, meta } = useTranslation();

now we can use the wrapper t():

<DIV>{t("text")}</DIV>

the hook is currently implemented only in app/(core)/components/Hero.jsx as a demonstration

  • app/(core)/locales directory:

in this folder we find the json files for each language (ar,de,en,es,fr,it)
example structure for ar.json (Arabic):

{
 "hello":"مرحبًا",
 "edit": "تعديل"
 }

currently I populated these json files with only the text from app/(core)/components/Hero.jsx

  • what is app/(core)/locales/meta.json ?

meta.json is a custom configuration file I speciffically made to allow us to do a progressive
transition from google translate to i18n it basically allows switching from google translate to manual translation for individual languages.

meta.json:

{
  "en": {
    "name": "English",
    "completed": true
  },
  "it": {
    "name": "Italian",
    "completed": false
  },
  "es": {
    "name": "Spanish",
    "completed": false
  },  
  "fr": {
    "name": "French",
    "completed": false
  },
  "de": {
    "name": "German",
    "completed": false
  },
  "ar": {
    "name": "Arabic",
    "completed": false
  }
}

the "completed":false indicate that the .json file for the language is not ready yet and Nextjs fallsback to using GoogleTranslate.
When "completed" is set to true it means the json file is complete and Nextjs switches to
i18n had translation for that language in the case there is an unwrapped text or the wrapped text doesn't have a matching key the original English text will be returned.

currently there is one minor unresolved issue when using handtranslation for a language and the page is reloaded Google translate ignores the "completed": true flag and translates the page.
Currently not causing any problems since there is no hand translation being actively used

@mattqdev
Copy link
Copy Markdown
Collaborator

thank you so much for this! If you fix the conflicts i'll merge it

@mattqdev
Copy link
Copy Markdown
Collaborator

eh sorry man my bad i merged a PR that was pretty similar to yours, so there are now more conflicts.
I hope it's not a problem for you fixing again.
Sorry again for this

@FaresAyadi055
Copy link
Copy Markdown
Contributor Author

eh sorry man my bad i merged a PR that was pretty similar to yours, so there are now more conflicts. I hope it's not a problem for you fixing again. Sorry again for this

The conflict was caused by a change in package-lock.json

@mattqdev
Copy link
Copy Markdown
Collaborator

oh yea maybe i'm just too tired :/

Thank you anyway for fixing it!

@mattqdev
Copy link
Copy Markdown
Collaborator

oh it hasn't fixed yet :/

@FaresAyadi055
Copy link
Copy Markdown
Contributor Author

FaresAyadi055 commented Mar 25, 2026

oh it hasn't fixed yet :/

I did fix it I just did a test because the merge behavior seemed strange, It's ready now

@mattqdev mattqdev merged commit b2035fb into physicshub:main Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants